<script setup lang="ts">
import {
  ColumnHeightOutlined,
  DeleteOutlined,
  DownOutlined,
  FormOutlined,
  PlusOutlined,
  ReloadOutlined,
  SettingOutlined,
  SisternodeOutlined,
  UpOutlined,
} from '@ant-design/icons-vue'
import type { MenuProps, PaginationProps, TableProps } from 'ant-design-vue'
import { enabledRoleStateByIdApi, queryRolePageApi, removeRoleByIdApi } from '~/api/setting/role.ts'
import { CommTablePagination, CommTableSize, CommTableSizeItems } from '~/components/comm-table/comm-table-data.ts'
import type { Page } from '~/api/base/base-model.ts'
import { RoleTableColumns } from '~/pages/setting/datas/role-data.ts'
import type { RoleReq, RoleResp } from '~/api/setting/model/role.ts'
import RoleEditModal from '~/pages/setting/components/role-edit-modal.vue'
import RolePermissionModal from '~/pages/setting/components/role-permission-modal.vue'

const message = useMessage()

const tableSize = shallowRef<string[]>(CommTableSize)
const sizeItems = CommTableSizeItems

const columns = RoleTableColumns
const loading = shallowRef(false)

const pageSource = shallowRef<Page<RoleResp>>()
const dataSource = shallowRef<RoleResp[]>([])

const pagination = reactive<PaginationProps>({
  ...CommTablePagination,
  total: pageSource.value?.total,
  onChange(current, pageSize) {
    pagination.pageSize = pageSize
    pagination.current = current
    init()
  },
})

const expand = ref(false)
const formQuery = reactive<RoleReq>({
  roleNameByLike: undefined,
  roleCodeByLike: undefined,
})

const options = computed(() => {
  return columns.value.map((item) => {
    if (item.dataIndex === 'action') {
      return {
        label: item.title,
        value: item.dataIndex,
        disabled: true,
      }
    }
    return {
      label: item.title,
      value: item.dataIndex,
    }
  })
})
const dropdownVisible = ref(false)
const getCheckList = computed(() => columns.value.map(item => item.dataIndex))
const state = reactive({
  indeterminate: false,
  checkAll: true,
  checkList: getCheckList.value,
})

async function init() {
  if (loading.value) {
    return
  }
  loading.value = true
  try {
    pageSource.value = await queryRolePageApi({
      param: formQuery,
      current: pagination.current,
      size: pagination.pageSize,
    })
    dataSource.value = pageSource.value?.records ?? []
  } catch (e) {
    console.log(e)
  } finally {
    loading.value = false
  }
}

async function onSearch() {
  pagination.current = 1
  await init()
}

async function onReset() {
  // 清空所有参数重新请求
  formQuery.roleNameByLike = undefined
  formQuery.roleCodeByLike = undefined
  await init()
}

/**
 * 密度切换
 *
 */
const handleSizeChange: MenuProps['onClick'] = (e) => {
  tableSize.value[0] = e.key as string
}

/**
 * 过滤
 *
 */
function filterAction(value: string[]) {
  return columns.value.filter((item) => {
    return value.includes(item.dataIndex)
  })
}

// 备份columns
const filterColumns = ref(filterAction(getCheckList.value))

/**
 * 全选/反选事件
 *
 */

function handleCheckAllChange(e: any) {
  Object.assign(state, {
    checkList: e.target.checked ? getCheckList.value : [],
    indeterminate: true,
  })
  filterColumns.value = e.target.checked ? filterAction(getCheckList.value) : filterColumns.value.filter(item => item.dataIndex === 'action')
}

watch(
  () => state.checkList,
  (val) => {
    state.indeterminate = !!val.length && val.length < getCheckList.value.length
    state.checkAll = val.length === getCheckList.value.length
  },
)

/**
 * 重置事件
 *
 */
function handleResetChange() {
  state.checkList = getCheckList.value
  filterColumns.value = filterAction(getCheckList.value)
}

/**
 * checkbox点击事件
 *
 */
function handleCheckChange(value: any) {
  filterColumns.value = filterAction(value)
}

const loadingOfSwitch = shallowRef(false)
/**
 * 角色状态开启或关闭
 */
async function onSwitchChange(item: RoleResp) {
  loadingOfSwitch.value = true
  const roleReq: RoleReq = {
    id: item.id,
  }
  const result = await enabledRoleStateByIdApi(roleReq)
  if (result) {
    loadingOfSwitch.value = false
    await init()
  }
}

/**
 * 删除功能
 *
 * @param roleResp
 */
async function onDeleteRole(roleResp: RoleResp) {
  const close = message.loading('删除中......')
  try {
    const roleReq: RoleReq = {
      id: roleResp.id,
    }
    const isDel = await removeRoleByIdApi(roleReq)
    if (isDel) {
      await init()
    }
    message.success('删除成功')
  } catch (e) {
    console.log(e)
  } finally {
    close()
  }
}

const openEdit = ref(false)
const optType = ref('create')
const roleResp = ref<RoleResp>({})

function openModalEditRole(opt: string, item?: RoleResp) {
  openEdit.value = true

  optType.value = opt
  if (opt === 'create') {
    roleResp.value = {}
  } else {
    roleResp.value = item || {}
  }
}

async function onSaveSuccess() {
  openEdit.value = false
  await onSearch()
}

const openPermission = ref(false)

function openModalPermissionAuth(item?: RoleResp) {
  openPermission.value = true

  roleResp.value = item
}

async function onAuthSuccess() {
  openPermission.value = false
  await onSearch()
}

onMounted(() => {
  init()
})
</script>

<template>
  <page-container>
    <a-card mb-4>
      <a-form :label-col="{ span: 7 }" :model="formQuery">
        <a-row :gutter="[15, 0]">
          <a-col :span="8">
            <a-form-item name="roleName" label="角色名称">
              <a-input v-model:value="formQuery.roleNameByLike" placeholder="请输入角色名称" />
            </a-form-item>
          </a-col>
          <a-col :span="8">
            <a-form-item name="roleCode" label="角色编码">
              <a-input v-model:value="formQuery.roleCodeByLike" placeholder="请输入角色编码" />
            </a-form-item>
          </a-col>
        </a-row>
        <a-row :span="24" style="text-align: right">
          <a-col :span="24">
            <a-space flex justify-end w-full>
              <a-button :loading="loading" type="primary" @click="onSearch">
                查询
              </a-button>
              <a-button :loading="loading" @click="onReset">
                重置
              </a-button>
              <a-button type="link" @click="expand = !expand">
                {{ expand ? '收起' : '展开' }}
                <UpOutlined v-if="expand" />
                <DownOutlined v-else />
              </a-button>
            </a-space>
          </a-col>
        </a-row>
      </a-form>
    </a-card>

    <a-card title="查询表格">
      <template #extra>
        <a-space size="middle">
          <a-button type="primary" @click="openModalEditRole('create')">
            <template #icon>
              <PlusOutlined />
            </template>
            新增
          </a-button>
          <a-tooltip title="刷新">
            <ReloadOutlined @click="onSearch" />
          </a-tooltip>
          <a-tooltip title="密度">
            <a-dropdown trigger="click">
              <ColumnHeightOutlined />
              <template #overlay>
                <a-menu v-model:selected-keys="tableSize" :items="sizeItems" @click="handleSizeChange" />
              </template>
            </a-dropdown>
          </a-tooltip>
          <a-tooltip title="列设置">
            <a-dropdown v-model:open="dropdownVisible" trigger="click">
              <SettingOutlined />
              <template #overlay>
                <a-card>
                  <template #title>
                    <a-checkbox v-model:checked="state.checkAll" :indeterminate="state.indeterminate" @change="handleCheckAllChange">
                      列选择
                    </a-checkbox>
                  </template>
                  <template #extra>
                    <a-button type="link" @click="handleResetChange">
                      重置
                    </a-button>
                  </template>
                  <a-checkbox-group v-model:value="state.checkList" :options="options" style="display: flex; flex-direction: column;" @change="handleCheckChange" />
                </a-card>
              </template>
            </a-dropdown>
          </a-tooltip>
        </a-space>
      </template>
      <a-table
        :loading="loading"
        :columns="filterColumns"
        :data-source="dataSource"
        :pagination="pagination"
        :size="tableSize[0] as TableProps['size']"
      >
        <template #bodyCell="scope">
          <template v-if="scope?.column?.dataIndex === 'indexNo'">
            {{ scope?.index + 1 }}
          </template>
          <template v-if="scope?.column?.dataIndex === 'stateId'">
            <a-switch
              :checked="(scope?.record?.stateValue)"
              :loading="loadingOfSwitch"
              checked-children="有效"
              un-checked-children="无效"
              @change="onSwitchChange(scope?.record)"
            />
          </template>

          <template v-if="scope?.column?.dataIndex === 'action'">
            <div>
              <span>
                <a><FormOutlined @click="openModalEditRole('edit', scope?.record)" /></a>
                <a-divider type="vertical" />
                <a><SisternodeOutlined @click="openModalPermissionAuth(scope?.record)" /></a>
                <a-divider type="vertical" />
                <a-popconfirm
                  v-if="dataSource.length"
                  title="确认删除?"
                  @confirm="onDeleteRole(scope?.record)"
                >
                  <a><DeleteOutlined /></a>
                </a-popconfirm>
              </span>
            </div>
          </template>
        </template>
      </a-table>
    </a-card>
    <RoleEditModal
      v-if="openEdit"
      v-model:open="openEdit"
      :opt-type="optType"
      :role-data="roleResp"
      @on-save-success="onSaveSuccess"
    />

    <RolePermissionModal
      v-if="openPermission"
      v-model:open="openPermission"
      :role-data="roleResp"
      @on-auth-success="onAuthSuccess"
    />
  </page-container>
</template>
